package com.otaku.admin.service;

import com.alibaba.fastjson.JSON;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;

import java.util.concurrent.TimeUnit;

/**
 * redis工具类
 */
@Component
public class RedisTemplateService {
    private final static Logger LOGGER = LoggerFactory.getLogger(RedisTemplateService.class);
    @Autowired
    private RedisTemplate<String, String> redisTemplate;

    public <T> boolean set(String key, T value) {

        try {
            //任意类型转换成String
            return setKey(key, value);
        } catch (Exception e) {
            LOGGER.error("登录失败，保存token失败：{}", e.getMessage());
            return false;
        }
    }

    public boolean delKey(String key) {
        try {
            Boolean delete = redisTemplate.delete(key);
            return delete;
        } catch (Exception e) {
            LOGGER.error("删除token失败：{},错误原因", key, e.getMessage());
            return false;
        }
    }

    /**
     * 设置有过期时间的token存储
     *
     * @param key
     * @param value
     * @param timeOut 过期时间  单位秒
     * @param <T>
     * @return
     */
    public <T> boolean set(String key, Long timeOut, T value) {

        try {
            /**
             * 将token存入redis
             */
            boolean bool = setKey(key, value);
            /**
             * 设置token过期时间 时间单位 秒
             */
            if (bool) {
                redisTemplate.expire(key, timeOut, TimeUnit.SECONDS);
            }
            return bool;
        } catch (Exception e) {
            LOGGER.error("登录失败，保存token失败：{}", e.getMessage());
            return false;
        }
    }

    /**
     * token存入redis
     *
     * @param key
     * @param value
     * @param <T>
     * @return
     */
    private <T> boolean setKey(String key, T value) {
        //任意类型转换成String
        String val = beanToString(value);
        if (val == null || val.length() <= 0) {
            LOGGER.info("转换value类型失败，转换后val值为空");
            return false;
        }
        redisTemplate.opsForValue().set(key, val);
        return true;
    }


    public <T> T get(String key, Class<T> clazz) {
        try {
            String value = redisTemplate.opsForValue().get(key);

            return stringToBean(value, clazz);
        } catch (Exception e) {
            return null;
        }
    }

    @SuppressWarnings("unchecked")
    private <T> T stringToBean(String value, Class<T> clazz) {
        if (value == null || value.length() <= 0 || clazz == null) {
            return null;
        }

        if (clazz == int.class || clazz == Integer.class) {
            return (T) Integer.valueOf(value);
        } else if (clazz == long.class || clazz == Long.class) {
            return (T) Long.valueOf(value);
        } else if (clazz == String.class) {
            return (T) value;
        } else {
            return JSON.toJavaObject(JSON.parseObject(value), clazz);
        }
    }

    /**
     * @param value T任意类型
     * @return String
     */
    private <T> String beanToString(T value) {

        if (value == null) {
            return null;
        }
        Class<?> clazz = value.getClass();
        if (clazz == int.class || clazz == Integer.class) {
            return "" + value;
        } else if (clazz == long.class || clazz == Long.class) {
            return "" + value;
        } else if (clazz == String.class) {
            return (String) value;
        } else {
            return JSON.toJSONString(value);
        }
    }

    /**
     * 校验KEY是否存在
     *
     * @param key
     * @return
     */
    public boolean hasKey(String key) {
        return redisTemplate.hasKey(key);
    }
//    public static void main(String[] args) {
//        List<Token> list = new ArrayList<>();
//        for (int i = 0; i < 10; i++) {
//            Token token = new Token("id"+i,i,"token", DateUtils.getNowTimeStampTime());
//            list.add(token);
//        }
//        JSONObject object = new JSONObject();
//        object.put(StringConstantUtils.AUTH_LIST,list);
//        String o = object.toJSONString();
//        System.out.println(o);
//        GsonToken gsonToken = JSON.parseObject(o, GsonToken.class);
//        System.out.println(gsonToken.getAuth_list().toString());
//    }

}
